package com.agentframework.examples.jinhua;

import com.agentframework.core.annotation.Action;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;

import java.util.Set;

import static com.agentframework.core.agent.Agent.SEND_TO;
import static com.agentframework.core.agent.Agent.VIEW_TO;

/**
 * 处理玩家下注动作
 * @author wangjun
 */
@Action(name = "bet")
public class BetAction extends JinhuaDealerAction {
    
    public BetAction(JinhuaTool jinhuaTool) {
        super("bet", jinhuaTool);
    }
    
    @Override
    protected String getFormatInstruction() {
        return """
            你需要处理玩家的下注请求，请必须且只能返回如下JSON格式：
            {
                "playerId": "玩家ID（例如：e9fc1d4d）",
                "betAmount": "下注金额",
                "message": "确认玩家下注的消息",
                "betStatus": "下注状态(0表示失败（失败原因，下注金额不对，余额不足等）1表示成功)",
                "nextPlayerId": "下一个玩家"
            }
            
            错误返回：
            由于玩家已看牌，下注金额需至少为10倍。以下将处理你的下注请求。玩家e9fc1d4d蒙牌下注100 {
                "playerId": "0d8f6620",
                "betAmount": "10",
                "message": "玩家0d8f6620看牌后下注10",
                "betStatus": "1",
                "nextPlayerId": "4bea25a3"
            }
            
            正确示范：
            {
                "playerId": "e9fc1d4d",
                "betAmount": "100",
                "message": "由于玩家已看牌，下注金额需至少为10倍。以下将处理你的下注请求。玩家e9fc1d4d蒙牌下注100",
                "betStatus": "1",
                "nextPlayerId": "下一个玩家ID（例如：e9fc2db4d）"
            }
            
            特别注意：
            1. playerId 必须使用玩家的实际ID（例如：e9fc1d4d）
            2. 如果你需要对当前玩家下注做出说明的话，相关说明内容必须包含在返回的json格式的message字段内，严禁放到json结构之外
            3. 请仔细对照错误返回跟正确示范的内容，再确定返回的内容
            """;
    }

    @Override
    protected void doHandleResponseMessage(Message message, Object response) {
        BetResp betResp = (BetResp) response;
        String playerId = betResp.playerId();
        String messageContent = betResp.message();

        // 通知玩家下注成功
//        Message betMessage = new UserMessage(messageContent);
//        betMessage.getMetadata().put(Agent.MSG_FROM, agent.getAgentId());
//        betMessage.getMetadata().put(Agent.SEND_TO, Set.of(playerId));
//        betMessage.getMetadata().put(VIEW_TO, Set.of(playerId));
//        publishMessage(betMessage);

        if (betResp.betStatus() == 0) {
            // 下注失败 让玩家重新下注
            Message rebetMessage = new UserMessage(messageContent);
            rebetMessage.getMetadata().put(SEND_TO, Set.of(playerId));
            publishMessage(rebetMessage);
            return;
        }

        int betAmount = betResp.betAmount();
        String nextPlayerId = betResp.nextPlayerId();
        boolean viewed = ((JinhuaEnvironment) getEnvironment()).getJinhuaGameState().getPlayer(playerId).isViewed();
        // 广播下注信息给所有玩家
        Message broadcastMessage = new UserMessage(String.format("玩家%s%s下注%d", playerId, !viewed ? "蒙牌" : "看牌", betAmount));
        broadcastMessage.getMetadata().put(SEND_TO, getPlayerIds());
        broadcastMessage.getMetadata().put(VIEW_TO, getPlayerIds());
        publishMessage(broadcastMessage);

        logger.debug("玩家{} 下注{}", playerId, betAmount);

        // 通知下一个玩家行动
        Message nextMessage = new UserMessage(messageContent);
        nextMessage.getMetadata().put(SEND_TO, Set.of(nextPlayerId));
        publishMessage(nextMessage);
    }

    @Override
    protected Class<?> getResponseType() {
        return BetResp.class;
    }

    record BetResp(String playerId, int betAmount, String message, int betStatus, String nextPlayerId) {

    }

} 